<template>
  <div class="header">
    <span>底图服务平台</span>
  </div>
  <div id="map"></div>
  <div class="city-btns">
    <div class="city-btn" @click="fitToExtent('tw')">台湾</div>
    <div class="city-btn" @click="fitToExtent('usa')">美国</div>
    <div class="city-btn">加载GEOJSON</div>
    <div class="city-btn" @click="clearGeojson">清空GEOJSON</div>
    <input class="img-input" type="file" @change="uploadFile" />
  </div>
  <div class="edit-forms" v-if="addFileLayer">
    <div class="edit-form">
      <input
        id="refresh-points"
        type="button"
        value="Refresh"
        @click="refreshStyle"
      />
      <h2>Points</h2>
      <div class="edit-form-elem">
        <label for="points-radius">Radius: </label>
        <input type="text" value="2" id="points-radius" />
        <br />
        <label for="points-fill">Fill: </label>
        <input type="text" value="#aa3300" id="points-fill" />
        <br />
        <label for="points-stroke">Stroke: </label>
        <input type="text" value="#ffffff" id="points-stroke" />
      </div>
    </div>

    <div class="edit-form">
      <input
        id="refresh-lines"
        type="button"
        value="Refresh"
        @click="refreshStyle"
      />
      <h2>Lines</h2>
      <div class="edit-form-elem">
        <label for="line-wdith">Line Width: </label>
        <input type="text" value="2" id="line-wdith" />
        <br />
        <label for="line-color">Line Color: </label>
        <input type="text" value="#aa3300" id="line-color" />
      </div>
    </div>

    <div class="edit-form">
      <input
        id="refresh-polygons"
        type="button"
        value="Refresh"
        @click="refreshStyle"
      />
      <h2>Polygons</h2>
      <div class="edit-form-elem">
        <label for="polygon-width">Outline Width: </label>
        <input type="text" value="2" id="polygon-width" />
        <br />
        <label for="polygon-color">Line Color: </label>
        <input type="text" value="blue" id="polygon-color" />
        <br />
        <label for="polygon-fill">Fill: </label>
        <input type="text" value="blue" id="polygon-fill" />
      </div>
    </div>
  </div>
</template>

<script setup>
import L from "leaflet";
import "proj4leaflet";
import "leaflet/dist/leaflet.css";
import axios from "axios";

import {
  ref,
  onMounted,
  onBeforeUnmount,
  defineProps,
  defineExpose
} from "vue";

let map;
let addFileLayer = ref(null);

function elementToJSON(element) {
  const obj = {};

  if (element.nodeType === 3) {
    obj["#text"] = element.nodeValue;
  } else {
    if (element.hasChildNodes()) {
      for (let i = 0; i < element.childNodes.length; i++) {
        const child = element.childNodes[i];
        const nodeName = child.nodeName;
        if (obj[nodeName] === undefined) {
          obj[nodeName] = elementToJSON(child);
        } else {
          if (!Array.isArray(obj[nodeName])) {
            obj[nodeName] = [obj[nodeName]];
          }
          obj[nodeName].push(elementToJSON(child));
        }
      }
    }
  }
  return obj;
}

function zeroFill(num, len, radix) {
  var str = num.toString(radix || 10);
  while (str.length < len) {
    str = "0" + str;
  }
  return str;
}
const getTileUrl = function (coords) {
  // increment our x/y coords by 1 so they match our tile naming scheme
  const oo = "00000000";

  const z = "L" + zeroFill(coords.z, 2, 10);
  var xx = coords.x.toString(16);
  var x = "C" + oo.substring(0, 8 - xx.length) + xx;
  var yy = coords.y.toString(16).toLowerCase(); //减1
  var y = "R" + oo.substring(0, 8 - yy.length) + yy;

  const tilePath =
    "http://localhost:5714/_alllayers/" + z + "/" + y + "/" + x + ".png";
  return tilePath;
};

const addImgLayer = () => {
  axios
    .get("http://localhost:5714/_alllayers/conf.xml")
    .then(response => {
      const parser = new DOMParser();
      const xmlDoc = parser.parseFromString(response.data, "text/xml");
      const jsonObj = elementToJSON(xmlDoc);

      const array =
        jsonObj["CacheInfo"]["TileCacheInfo"]["LODInfos"]["LODInfo"];
      const resolutions = array.map(it => it["Resolution"]["#text"]["#text"]);

      const scales = array.map(it => it["Scale"]["#text"]["#text"]);

      const firstRes = resolutions[0];
      const newResolutions = [firstRes];

      for (let i = 1; i < 16; i++) {
        const res = Number(firstRes) / Math.pow(2, i);
        newResolutions.push(`${res}`);
      }

      const originX = Number(
        jsonObj.CacheInfo.TileCacheInfo.TileOrigin.X["#text"]["#text"]
      );
      const originY = Number(
        jsonObj.CacheInfo.TileCacheInfo.TileOrigin.Y["#text"]["#text"]
      );
      const tileSize = Number(
        jsonObj.CacheInfo.TileCacheInfo.TileRows["#text"]["#text"]
      );
      const crs = new L.Proj.CRS(
        "EPSG:4326",
        "+title=WGS 84 (long/lat) +proj=longlat +ellps=WGS84 +datum=WGS84 +units=degrees",
        {
          resolutions: newResolutions,
          origin: [originX, originY]
        }
      );
      map = L.map("map", { crs: crs }).setView([23.044333, 121.509064], 8);

      const tiles = L.tileLayer(
        "http://localhost:5714/_alllayers/{z}/{y}/{x}.png",
        {}
      );
      tiles.getTileUrl = getTileUrl;
      map.addLayer(tiles);
    })
    .catch(error => {
      console.error(error);
    });
};
onMounted(() => {
  //调用加载
  addImgLayer();
});
</script>
<style lang="less">
.header {
  width: 100%;
  height: 50px;
  background: #000;
  color: #fff;
  padding: 0 24px;
  text-align: left;
  > span {
    font-size: 20px;
    line-height: 50px;
  }
}

#map {
  flex: 1;
}

.city-btns {
  position: absolute;
  top: 60px;
  left: 60px;
  z-index: 999;
  display: flex;
  gap: 20px;
}

.city-btns > .city-btn {
  background: #ddd;
  padding: 10px 20px;
  font-size: 14px;
  font-weight: bold;
  cursor: pointer;
  border-radius: 10px;
}

.city-btn:hover {
  background: #ccc;
}

.img-input {
  width: 136px;
  height: 40px;
  position: absolute;
  top: 0;
  left: 177px;
  opacity: 0;
  cursor: pointer;
}

.edit-forms {
  position: absolute;
  bottom: 10px;
  right: 20px;
  display: flex;
  padding: 10px;
  border: 1px solid #000;

  .edit-form {
    display: inline-block;
    margin: 5px;
    padding: 10px;
    border: 1px solid black;
    white-space: nowrap;
  }

  .edit-form h2 {
    font-size: 1.5em;
  }

  .edit-form input[type="button"] {
    float: right;
  }

  .edit-form-elem label {
    display: inline-block;
    width: 85px;
  }

  .edit-form-elem input[type="text"],
  .edit-form-elem select {
    width: 130px;
  }
}
</style>
